home *** CD-ROM | disk | FTP | other *** search
- /*
- * This is the main part
- */
-
- #include <intuition/screens.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <string.h>
-
- #include "video.h"
- #include "proto.h"
- #include <sys/types.h>
- #include <signal.h>
-
- #include <proto/timer.h>
- #include <devices/timer.h>
-
- #include <proto/asyncio.h>
- #include <proto/asl.h>
-
- #include "util.h"
-
- #define HELP_TEXT "FILES\t- filename(s) of MPEG stream(s). Supports wildcards.\n\
- NOB\t- ignore and not display any B frames.\n\
- NOP\t- ignore and not display any P frames.\n\
- LOOP\t- makes the player loop back to the beginning after reaching the end.\n\
- EACHSTAT- causes statistics to be displayed after each frame.\n\
- \t Only valid when compiled with -DANALYSIS\n\
- NODISPLAY- dithers, but does not display, usually used for\n\
- \t testing and timing purposes.\n\
- QUIET\t- supresses printing of frame numbers, timing information,\n\
- \t and most error messages.\n\
- DITHER\t- selects from a variety of dither options.\n\
- \t The possible values are:\n\
- \t\tcolor\n\
- \t\thiresham\n\
- \t\tham6\n\
- \t\tcybergfx\n\
- \t\tcybergfxgray\n\
- \t\tgray\n\
- \t\tvlayer\n\
- \t\tvlayergray\n\
- \t\tpivpip\n\
- \t\tnone\n\
- PUBSCREEN- open window on selected \"deep\" public screen. Only valid with\n\
- \t DITHER cybergfx or cybergfxgray. Use with \"DEFAULT\" to open on current\n\
- \t default public screen. When used with vlayer(gray), may name any\n\
- \t public screen, as long as it is the screen of a gfx-board compatible\n\
- \t with cgxvideo.library.\n\
- MODEID\t- select modeid for screen to open and play on.\n\
- FRAMERATE- speed in frames per second. (0 - as fast as possible).\n\
- BUFFER\t- size of the I/O buffer (default - 65536).\n\
- FULL\t- open full-screen, borderless window. Most useful with vlayer(gray).\n"
-
- #define TEMPLATE "FILES/M,NOB/S,NOP/S,LOOP/S,EACHSTAT/S,ND=NODISPLAY/S,QUIET/S,DITHER/K,PS=PUBSCREEN/K,MODEID/K,FRAMERATE=FPS/K,BUFFER=BUF/K,FULL/S"
-
- #define OPT_FILES 0
- #define OPT_NOB 1
- #define OPT_NOP 2
- #define OPT_LOOP 3
- #define OPT_EACHSTAT 4
- #define OPT_NODISPLAY 5
- #define OPT_QUIET 6
- #define OPT_DITHER 7
- #define OPT_PUBSCREEN 8
- #define OPT_MODEID 9
- #define OPT_FPS 10
- #define OPT_BUFFER 11
- #define OPT_FULL 12
- #define OPT_COUNT 13
-
- #define AP_BUFFSIZE 240
-
- struct Files /* to keep the names from MatchFirst() etc or ASL req... */
- {
- unsigned char *name;
- struct Files *next;
- };
-
- const char *dither_names = "ham6\1color\1hiresham\1ham6\1cybergfx\1cybergfxgray\1vlayer\1vlayergray\1pivpip\1none";
- /* 01234 56789 1113151719 2123 2527293133 353739414345 47495153 5557596163 65676971
- got it? :) 10 12141618 202224 26283032 34363840424446 485052 545658606264 666870 72
- */
-
- char animname[1024];
- char pubscreen_name[MAXPUBSCREENNAME + 1];
- char *pubname_ptr;
-
- /* Declaration of global variable to hold dither info. */
-
- int ditherType;
-
- /* size of the io buffer */
-
- int buf_length = 65536;
-
- /* Global file pointer to incoming data. */
- struct AsyncFile *input;
-
- /* End of File flag. */
- int EOF_flag = 0;
-
- /* Loop flag. */
- int loopFlag = 0;
-
- /* Quiet flag. */
- int quietFlag = 0;
-
- /* full screen output */
- int fullFlag = 0;
-
- /* User wants to quit? */
- int doneFlag = 0;
-
- /* how many files to show? */
- int number_of_files = 0;
-
- /* Display image on screen? */
- int noDisplayFlag = 0;
-
- /* Setjmp/Longjmp env. */
- jmp_buf env;
-
- /* HAM6 rendering / HAM hires flag */
- extern int ham6, lores;
-
- /* modeid of CyberGraphX screen */
- unsigned long modeid = 0xffffffff;
-
- /* are we going to play on the Public Screen? */
- int cyber_pub = 0;
-
- /* Framerate, -1: specified in stream (default)
- 0: as fast as possible
- N (N>0): N frames/sec
- */
- int framerate = -1;
-
- /* these are for timer.device */
- struct Library *TimerBase;
- struct MsgPort *TimerMP; /* Message port pointer */
- struct timerequest *TimerIO; /* I/O structure pointer */
-
- /* Method of picture conversion */
- void (*DoDitherImage)(unsigned char *l, unsigned char *Cr, unsigned char *Cb,
- unsigned char *disp, int h, int w);
-
- static char version[]="$VER: aMiPEG 1.1 " __AMIGADATE__;
-
-
- /*
- *--------------------------------------------------------------
- *
- * int_handler --
- *
- * Handles Cntl-C interupts..
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
- void int_handler(int dummy)
- {
- if (!quietFlag) fprintf(stderr, "Interrupted!\n");
- if (curVidStream) DestroyVidStream(curVidStream);
-
- if(input)
- {
- CloseAsync(input);
- input = NULL;
- }
-
- exit(1);
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * init_timer --
- *
- * Prepare timer.device and IORequest for later use
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void init_timer(void)
- {
- /* Create port for timer device communications */
- if(TimerMP = CreatePort(NULL, 0))
- /* Create message block for device IO */
- if(TimerIO = (struct timerequest *)CreateExtIO(TimerMP, sizeof(struct timerequest)))
-
- /* Open the timer device with UNIT_MICROHZ */
- if(!OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *)TimerIO, 0))
- {
- TimerBase = (struct Library *)TimerIO->tr_node.io_Device;
- TimerIO->tr_node.io_Command = TR_ADDREQUEST;
- return;
- }
- else
- fprintf(stderr, "Error: Can't open Timer.device\n");
- else
- fprintf(stderr, "Error: Can't create IO request\n");
- else
- fprintf(stderr, "Error: Can't create port\n");
-
- exit(1);
- }
- /*
- *--------------------------------------------------------------
- *
- * close_timer --
- *
- * Close timer.device, remove IORequest and message port
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void close_timer(void)
- {
- if(TimerBase)
- CloseDevice((struct IORequest *)TimerIO); /* Close Timer device */
-
- if(TimerIO)
- DeleteExtIO((struct IORequest *)TimerIO);
-
- if(TimerMP)
- DeletePort(TimerMP);
- }
-
- /*
- *--------------------------------------------------------------
- *
- * main --
- *
- * Parses command line, starts decoding and displaying.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void main(int argc, char **argv)
- {
- static VidStream *theStream;
- extern int lores;
- LONG opts[OPT_COUNT];
- struct RDArgs *rdargs;
- struct FileRequester *fr;
- struct Library *AslBase;
- unsigned char **fnames;
- struct AnchorPath *ap;
- struct Files *namestuff=NULL;
- struct Files *p;
- struct Files *q;
- int i;
- LONG err;
-
- ditherType = FULL_COLOR_DITHER;
- noDisplayFlag = 0;
-
- memset(opts, 0, sizeof(opts));
-
- if(rdargs = (struct RDArgs *)AllocDosObject(DOS_RDARGS, NULL))
- {
- rdargs->RDA_ExtHelp = HELP_TEXT;
-
- if(rdargs = ReadArgs(TEMPLATE, opts, rdargs))
- {
- if(opts[OPT_NOP])
- TogglePFlag();
-
- if(opts[OPT_NOB])
- ToggleBFlag();
-
- if(opts[OPT_DITHER])
- {
- switch(strstr(dither_names, strlwr((char *)opts[OPT_DITHER])) - dither_names)
- {
- case 5: /* color */
- ditherType = FULL_COLOR_DITHER;
- break;
-
- case 11: /* hiresham */
- ditherType = FULL_COLOR_DITHER;
- lores = FALSE;
- break;
-
- case 0: /* ham6 */
- ditherType = FULL_COLOR_DITHER;
- ham6 = TRUE;
- break;
-
- case 25: /* cybergfx */
- ditherType = CYBERGFX_DITHER;
- break;
-
- case 34: /* cybergfxgray */
- ditherType = CYBERGFXGRAY_DITHER;
- break;
-
- case 42: /* gray */
- ditherType = GRAY_DITHER;
- break;
-
- case 47:
- ditherType = CYBERGFXVLAYER_DITHER;
- break;
-
- case 54:
- ditherType = CYBERGFXVLAYERGRAY_DITHER;
- break;
-
- case 65:
- ditherType = PIV_DITHER;
- break;
-
- case 72:
- ditherType = NO_DITHER;
- break;
-
- default:
- fprintf(stderr, "You should specify legal dither name after DITHER keyword.\n");
- FreeArgs(rdargs);
- exit(10);
- }
- }
-
- if(opts[OPT_EACHSTAT])
- #ifdef ANALYSIS
- showEachFlag = 1;
- #else
- {
- fprintf(stderr, "To use EACHSTAT, recompile with DEFINE ANALYSIS in CFLAGS\n");
- exit(1);
- }
- #endif
-
- if(opts[OPT_QUIET])
- quietFlag = 1;
-
- if(opts[OPT_LOOP])
- loopFlag = 1;
-
- if(opts[OPT_NODISPLAY])
- noDisplayFlag = 1;
-
- if(opts[OPT_PUBSCREEN])
- {
- if(!stricmp("default", (char *)opts[OPT_PUBSCREEN]))
- pubname_ptr = NULL;
- else
- {
- strcpy(pubscreen_name, (char *)opts[OPT_PUBSCREEN]);
- pubname_ptr = pubscreen_name;
- }
-
- cyber_pub = 1;
- }
-
- if(opts[OPT_MODEID])
- if(sscanf((char *)opts[OPT_MODEID], "%x", &modeid) != 1)
- {
- fprintf(stderr, "ModeID should be an hexadecimal value.\n");
- FreeArgs(rdargs);
- exit(10);
- }
-
- if(opts[OPT_FPS])
- if(sscanf((char *)opts[OPT_FPS], "%d", &framerate) != 1)
- {
- fprintf(stderr, "You should specify a number after FRAMERATE keyword.\n");
- FreeArgs(rdargs);
- exit(10);
- }
-
- if(opts[OPT_BUFFER])
- if(sscanf((char *)opts[OPT_BUFFER], "%d", &buf_length) != 1)
- {
- fprintf(stderr, "You should specify a number after BUFFER keyword.\n");
- FreeArgs(rdargs);
- exit(10);
- }
-
- if(opts[OPT_FULL])
- fullFlag = 1;
-
- fnames = (char **) opts[OPT_FILES];
-
- if(fnames!=NULL)
- {
-
- if ((ap = malloc (sizeof (struct AnchorPath) + AP_BUFFSIZE)))
- {
- memset(ap, 0, sizeof(struct AnchorPath) + AP_BUFFSIZE);
- ap->ap_Strlen = AP_BUFFSIZE;
-
- while (*fnames != NULL)
- {
-
- for (err = MatchFirst (*fnames, ap); (err == 0); err = MatchNext (ap))
- {
- number_of_files++;
-
- if ((q = malloc (sizeof (struct Files))) && (q->name=malloc(AP_BUFFSIZE)))
- {
- struct Files *old_pointer = NULL;
-
- if(ap->ap_Buf[0]) // dirty hack for PIPE: stuff
- strcpy (q->name, ap->ap_Buf);
- else
- strcpy (q->name, *fnames);
-
- p=namestuff;
-
- if(p==NULL)
- {
- namestuff=q;
- q->next = NULL;
- }
- else
- {
-
- /* crappy"sort" :) O(n^2) at worst */
-
- /* Move slowly down the list and try to fit in the structure: */
- while (p && stricmp (p->name, q->name) <= 0)
- {
- old_pointer = p;
- p = p->next;
- }
-
- if (p)
- {
- if (old_pointer)
- {
- q->next = old_pointer->next;
- old_pointer->next = q;
- }
- else
- {
- q->next = namestuff;
- namestuff = q;
- }
- }
- else
- {
- old_pointer->next=q;
- q->next = NULL;
- }
- }
- }
- }
- if(err==ERROR_OBJECT_NOT_FOUND && !quietFlag)
- printf("Couldn't show '%s': object not found\n", *fnames);
- MatchEnd (ap);
- fnames++;
- }
- free(ap);
- }
- }
- else
- {
- if ((AslBase = OpenLibrary ("asl.library", 37)) != NULL)
- {
-
- if ((fr = (struct FileRequester *) AllocAslRequestTags (ASL_FileRequest,
- ASLFR_TitleText, (ULONG) "Select files to play",
- ASLFR_InitialPattern, (ULONG) "#?.mpg",
- (AslBase->lib_Version < 38) ? TAG_DONE :
- ASLFR_DoMultiSelect, TRUE,
- ASLFR_DoPatterns, TRUE,
- TAG_DONE)))
- {
- if (AslRequest (fr, NULL))
- {
- for (i = (fr->fr_NumArgs)-1; i>=0 ; i--)
- {
- number_of_files++;
-
- if ((q = malloc (sizeof (struct Files))) && (q->name=malloc(AP_BUFFSIZE)))
- {
- strcpy (q->name, fr->fr_Drawer);
- AddPart (q->name, fr->fr_ArgList[i].wa_Name, AP_BUFFSIZE);
-
- p=namestuff;
- if(p==NULL)
- {
- namestuff=q;
- q->next=NULL;
- }
- else
- {
- q->next=p;
- namestuff=q;
- }
- }
- }
- }
- FreeAslRequest(fr);
- }
- else
- {
- printf ("Can't allocate file requester.\n");
- CloseLibrary(AslBase);
- FreeArgs(rdargs);
- return;
- }
- CloseLibrary(AslBase);
- }
- else
- {
- fprintf(stderr, "Error opening asl.library V37\n");
- FreeArgs(rdargs);
- return;
- }
- }
-
- p=namestuff;
-
- if(p!=NULL)
- {
- signal(SIGINT, int_handler);
-
- init_tables();
- init_timer();
-
- switch (ditherType)
- {
- case PIV_DITHER:
- CheckPIV();
- InitColorDither();
- modeid = InitP96Display(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawP96Image;
- DoDitherImage = ColorDitherImage_VideoLayerYCbCr;
-
- break;
-
- case CYBERGFXVLAYERGRAY_DITHER:
- InitColorDither();
- modeid = InitCyberGfxDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage;
- DoDitherImage = ColorDitherImage_VideoLayerGray;
-
- break;
-
- case CYBERGFXVLAYER_DITHER:
- InitColorDither();
- modeid = InitCyberGfxDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage;
- DoDitherImage = ColorDitherImage_VideoLayerYCbCr;
-
- break;
-
- case CYBERGFX_DITHER:
- InitColorDither();
- modeid = InitCyberGfxDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage;
- DoDitherImage = ColorDitherImage_RGB;
- break;
-
- case CYBERGFXGRAY_DITHER:
- InitColorDither();
- modeid = InitCyberGfxDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage;
- DoDitherImage = NoDitherImage;
- break;
-
- case GRAY_DITHER:
- InitColorDither();
- modeid = InitGrayDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawGrayImage;
- DoDitherImage = NoDitherImage;
- break;
-
- case FULL_COLOR_DITHER:
- InitColorDither();
- InitColorDisplay();
- break;
-
- case NO_DITHER:
- HAM8_draw = (void (*)(void *, int, int)) NoDitherImage; // method casting ... argh!
- DoDitherImage = NoDitherImage;
- break;
- }
- }
-
- /*
- * The new restart handling has not been checked out very closely with changing
- * (non)intra scale matrixes!
- */
-
- while(p!=NULL && doneFlag != DONE_REALLY)
- {
- if(number_of_files == 1 && doneFlag == DONE_NOT_REALLY)
- break;
-
- while(p!=NULL && !(input = OpenAsync(p->name, MODE_READ, buf_length)))
- {
- fprintf(stderr, "Could not open file %s\n", p->name);
- p=p->next;
- }
-
- if(p==NULL) break;
- if(!quietFlag) printf("file: %s\n", p->name);
- strcpy(animname, p->name);
- p=p->next;
-
- theStream = NewVidStream(buf_length);
-
- mpegInitVidRsrc();
-
- EOF_flag=0;
- sys_layer=-1;
- totNumFrames=0;
-
- realTimeStart = ReadSysClock();
-
- if (setjmp(env) == 0)
- while (mpegVidRsrc(0, theStream));
-
- if(input)
- {
- CloseAsync(input);
- input = NULL;
- }
-
- if(p==NULL && loopFlag)
- p=namestuff;
-
- }
-
- p=namestuff;
- while(p)
- {
- free(p->name);
- q=p;
- p=p->next;
- free(q);
- }
-
- FreeArgs(rdargs);
- }
-
- FreeDosObject(DOS_RDARGS, rdargs);
- }
- else
- {
- PrintFault(IoErr(), argv[0]);
- exit(10);
- }
- }
-
-
- /*
- * Dummy display method
- *
- */
- void NoDitherImage(unsigned char *l, unsigned char *Cr, unsigned char *Cb,
- unsigned char *disp, int h, int w)
- {}
-